"""结果输出模块

负责将处理后的视频分析结果保存为指定格式（TXT）
"""

import os
import logging
from typing import Dict, Any, List, Optional

from config.encoding_categories import OUTPUT_ORDER
from .utils import ensure_directory, write_file

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class ResultExporter:
    """结果输出器类，负责将处理后的结果保存为指定格式"""
    
    def __init__(self, output_dir: str):
        """初始化结果输出器
        
        Args:
            output_dir: 输出目录路径
        """
        self.output_dir = output_dir
        # 确保输出目录存在
        ensure_directory(output_dir)
        logger.info(f"结果输出器初始化，输出目录: {output_dir}")
    
    def export_to_txt(self, result: Dict[str, Any]) -> str:
        """将结果导出为TXT格式
        
        Args:
            result: 处理后的结果
        
        Returns:
            保存的文件路径
        """
        try:
            if not result:
                raise ValueError("结果数据不能为空")
                
            # 获取视频ID
            video_id = self._extract_video_id(result)
            
            # 生成文件名
            filename = self._get_output_filename(result)
            file_path = os.path.join(self.output_dir, filename)
            
            # 格式化内容
            content = self._format_result_for_export(result)
            
            # 写入文件
            write_file(file_path, content)
            
            logger.info(f"成功导出TXT文件: {file_path}")
            return file_path
        except Exception as e:
            logger.error(f"导出TXT文件失败: {str(e)}")
            raise
    
    def _format_result_for_export(self, result: Dict[str, Any]) -> str:
        """格式化结果用于导出
        
        Args:
            result: 处理后的结果
        
        Returns:
            格式化后的内容
        """
        lines = []
        
        # 按照预定义的输出顺序格式化
        for field in OUTPUT_ORDER:
            if field in result:
                value = result[field]
                lines.append(f"{field}: {value}")
        
        # 添加分隔线
        lines.append("-" * 50)
        
        # 添加剩余的字段
        for key, value in result.items():
            if key not in OUTPUT_ORDER:
                lines.append(f"{key}: {value}")
        
        # 连接所有行
        return "\n".join(lines)
    
    def _get_output_filename(self, result: Dict[str, Any]) -> str:
        """获取输出文件名
        
        Args:
            result: 处理后的结果
        
        Returns:
            输出文件名
        """
        # 尝试从结果中获取视频ID
        if "视频ID" in result:
            return f"{result['视频ID']}.txt"
        
        # 如果没有视频ID，生成一个临时文件名
        import uuid
        return f"video_{uuid.uuid4().hex[:8]}.txt"
    
    def _generate_statistics(self, results: List[Dict[str, Any]]) -> Dict[str, Any]:
        """生成统计信息
        
        Args:
            results: 结果列表
        
        Returns:
            统计信息字典
        """
        stats = {
            "total_videos": len(results)
        }
        
        # 获取所有编码字段
        encoding_fields = [field for field in OUTPUT_ORDER]
        
        for field in encoding_fields:
            distribution = {}
            for result in results:
                value = result.get(field, '其他')
                distribution[value] = distribution.get(value, 0) + 1
            stats[field] = distribution
        
        return stats
    
    def verify_export(self, file_path: str) -> tuple[bool, str]:
        """验证导出文件
        
        Args:
            file_path: 文件路径
        
        Returns:
            (是否有效, 消息)
        """
        try:
            # 检查文件是否存在
            if not os.path.exists(file_path):
                return False, "文件不存在"
            
            # 检查文件内容是否为空
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                
            if not content.strip():
                return False, "文件内容为空"
            
            return True, "导出验证成功"
        except Exception as e:
            return False, f"验证失败: {str(e)}"
    
    def export_multiple_results(self, results: List[Dict[str, Any]], batch_name: Optional[str] = None) -> List[str]:
        """批量导出多个结果
        
        Args:
            results: 结果列表
            batch_name: 批次名称，如果提供则创建子目录
        
        Returns:
            保存的文件路径列表
        """
        file_paths = []
        
        # 确定输出目录
        current_output_dir = self.output_dir
        if batch_name:
            current_output_dir = os.path.join(self.output_dir, batch_name)
            ensure_directory(current_output_dir)
            logger.info(f"批量导出到子目录: {current_output_dir}")
        
        # 逐个导出结果
        for result in results:
            try:
                # 获取视频ID
                video_id = self._extract_video_id(result)
                
                # 临时修改输出器的输出目录
                original_output_dir = self.output_dir
                self.output_dir = current_output_dir
                
                try:
                    file_path = self.export_to_txt(result, video_id)
                    file_paths.append(file_path)
                finally:
                    # 恢复原始输出目录
                    self.output_dir = original_output_dir
                    
            except Exception as e:
                logger.error(f"导出单个结果失败: {str(e)}")
        
        logger.info(f"批量导出完成，成功导出 {len(file_paths)}/{len(results)} 个结果")
        return file_paths
    
    def _extract_video_id(self, result: Dict[str, Any]) -> str:
        """从结果中提取视频ID
        
        Args:
            result: 处理后的结果
        
        Returns:
            视频ID
        """
        # 尝试从多个可能的字段中提取视频ID
        id_fields = ['视频ID', '视频编号', 'id', 'video_id', 'vid', 'url', '视频URL']
        
        for field in id_fields:
            if field in result:
                value = str(result[field])
                
                # 如果是URL，尝试从中提取ID
                if field in ['url', '视频URL']:
                    # 简单的URL处理逻辑，可以根据实际情况扩展
                    # 例如：从抖音分享链接中提取
                    import re
                    match = re.search(r'video/([^/?]+)', value)
                    if match:
                        return match.group(1)
                    
                    # 如果没提取到，使用整个URL的哈希值
                    import hashlib
                    return hashlib.md5(value.encode()).hexdigest()[:16]
                
                return value
        
        # 如果都没找到，生成一个临时ID
        import uuid
        return f"temp_{uuid.uuid4().hex[:16]}"
    
    def export_summary(self, results: List[Dict[str, Any]], filename: str = "summary.txt") -> str:
        """导出结果汇总
        
        Args:
            results: 结果列表
            filename: 汇总文件名
        
        Returns:
            保存的文件路径
        """
        try:
            file_path = os.path.join(self.output_dir, filename)
            
            # 生成汇总内容
            lines = ["视频编码分析汇总报告", "=" * 50, ""]
            lines.append(f"总视频数: {len(results)}")
            lines.append("")
            
            # 统计编码类目的分布
            if results:
                # 获取所有编码字段
                encoding_fields = [field for field in OUTPUT_ORDER]
                
                for field in encoding_fields:
                    # 统计该字段的分布
                    distribution = {}
                    for result in results:
                        value = result.get(field, '其他')
                        distribution[value] = distribution.get(value, 0) + 1
                    
                    # 添加统计信息
                    lines.append(f"\n{field}统计:")
                    lines.append("-" * 30)
                    
                    # 按数量排序输出
                    for value, count in sorted(distribution.items(), key=lambda x: x[1], reverse=True):
                        percentage = (count / len(results)) * 100
                        lines.append(f"{value}: {count} ({percentage:.1f}%)")
            
            # 写入文件
            write_file(file_path, "\n".join(lines))
            
            logger.info(f"成功导出汇总文件: {file_path}")
            return file_path
        except Exception as e:
            logger.error(f"导出汇总文件失败: {str(e)}")
            raise
    
    def verify_export(self, file_path: str) -> bool:
        """验证导出文件是否成功创建并且内容正确
        
        Args:
            file_path: 导出的文件路径
        
        Returns:
            是否验证成功
        """
        try:
            # 检查文件是否存在
            if not os.path.exists(file_path):
                logger.error(f"验证失败：文件不存在 - {file_path}")
                return False
            
            # 检查文件大小
            file_size = os.path.getsize(file_path)
            if file_size == 0:
                logger.error(f"验证失败：文件为空 - {file_path}")
                return False
            
            # 检查文件内容格式
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                
                # 检查是否包含基本格式特征
                if len(content) < 10:  # 至少应该有一些内容
                    logger.error(f"验证失败：文件内容过短 - {file_path}")
                    return False
                
                # 检查是否包含预期的分隔符或格式特征
                if "-" * 50 not in content and ":" not in content:
                    logger.warning(f"验证警告：文件可能格式不正确 - {file_path}")
            
            logger.info(f"文件验证成功 - {file_path}")
            return True
        except Exception as e:
            logger.error(f"验证文件失败: {str(e)}")
            return False